#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: liang kang
@contact: gangkanli1219@gmail.com
@time: 2018/5/24 10:43
@desc: 
"""
import xml.etree.ElementTree as ET

import numpy as np

from utils.data import Nodule, Roi


class XmlDecoder(object):

    def __init__(self, file_name, frame_instance, patient_id, series_id):
        self._filename = file_name
        self._nodule_list = []
        self._xml_ns = '{http://www.nih.gov}'
        self._frame_instance = frame_instance
        self.patient_id = patient_id
        self.series_id = series_id

    def _key(self, string):
        return self._xml_ns + string

    def _read_xml_file(self):
        xml_file = open(self._filename, 'rt')
        root = ET.parse(xml_file).getroot()
        for readingSession in root.findall(self._xml_ns + 'readingSession'):
            for unblindedReadNodule in readingSession.findall(
                    self._key('unblindedReadNodule')):
                characteristics = unblindedReadNodule.find(
                    self._key('characteristics'))
                if characteristics is not None:
                    nodule = Nodule()
                    nodule.features = (
                        self._characteristics(characteristics))
                    for roi in unblindedReadNodule.findall(self._key('roi')):
                        roi_info = self._roi(roi)
                        if roi_info:
                            nodule.roi_list.append(roi_info)
                    if 0 != len(nodule.roi_list):
                        nodule.patient_id = self.patient_id
                        nodule.series_id = self.series_id
                        self._nodule_list.append(nodule)

    def _characteristics(self, characteristics):
        characteristics_str = [
            'subtlety', 'internalStructure', 'calcification', 'sphericity',
            'margin', 'lobulation', 'spiculation', 'texture', 'malignancy'
        ]
        feature = list(map(
            lambda x: [int(characteristics.find(self._key(x)).text)],
            characteristics_str))
        return dict(zip(characteristics_str, feature))

    def _roi(self, roi_pro):
        roi = Roi()
        roi.id = roi_pro.find(self._key('imageSOP_UID')).text
        if roi.id not in self._frame_instance:
            return None
        edge_maps = []
        for edge_Map in roi_pro.findall(self._key('edgeMap')):
            edge_maps.append(
                [self._frame_instance[roi.id],
                 int(edge_Map.find(self._key('yCoord')).text),
                 int(edge_Map.find(self._key('xCoord')).text)])
        roi.edge_maps = np.asarray(edge_maps)
        if 0 == len(edge_maps):
            return None
        return roi

    def update(self):
        self._read_xml_file()
        return self._nodule_list
